package com.nidu.demo.oauth2.gatewayimpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.PageQuery;
import com.alibaba.cola.dto.PageResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nidu.demo.oauth2.dto.OAuth2ClientListQry;
import com.nidu.demo.oauth2.dto.OAuth2ClientPageQry;
import com.nidu.demo.oauth2.convertor.OAuth2ClientConvertor;
import com.nidu.demo.oauth2.gateway.OAuth2ClientGateway;
import com.nidu.demo.oauth2.mapper.OAuth2ClientMapper;
import com.nidu.demo.oauth2.mapper.dataobject.OAuth2ClientDO;
import com.nidu.demo.oauth2.model.OAuth2Client;
import com.nidu.demo.oauth2.model.OAuth2ClientCriteria;
import com.nidu.demo.user.mapper.dataobject.UserDO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Set;
import java.util.List;

@Component
@RequiredArgsConstructor
public class OAuth2ClientGatewayImpl implements OAuth2ClientGateway {

    private final OAuth2ClientMapper mapper;
    private final OAuth2ClientConvertor convertor;

    @Override
    public OAuth2Client create(OAuth2Client client) {
        OAuth2ClientDO clientDO = convertor.toDataObject(client);
        mapper.insert(clientDO);
        return convertor.toDomainObject(clientDO);
    }

    @Override
    public OAuth2Client update(OAuth2Client client) {
        OAuth2ClientDO clientDO = convertor.toDataObject(client);
        mapper.updateById(clientDO);
        return convertor.toDomainObject(clientDO);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteById(id);
    }

    @Override
    public void deleteByIds(Set<Long> ids) {
        mapper.deleteByIds(ids);
    }

    @Override
    public OAuth2Client getById(Long id) {
        OAuth2ClientDO clientDO = mapper.selectById(id);
        if (clientDO == null) {
            return null;
        }
        return convertor.toDomainObject(clientDO);
    }

    @Override
    public OAuth2Client getByClientCode(String clientCode) {
        OAuth2ClientDO clientDO = mapper.selectByClientCode(clientCode);
        return clientDO != null ? convertor.toDomainObject(clientDO) : null;
    }

    @Override
    public List<OAuth2Client> listByCondition(OAuth2ClientCriteria criteria) {
        LambdaQueryWrapper<OAuth2ClientDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(criteria.getStatus() != null, OAuth2ClientDO::getStatus, criteria.getStatus());

        wrapper.in(!CollUtil.isEmpty(criteria.getClientIds()), OAuth2ClientDO::getId, criteria.getClientIds());
        wrapper.eq(!StrUtil.isEmpty(criteria.getClientCode()), OAuth2ClientDO::getClientCode, criteria.getClientCode());

        List<OAuth2ClientDO> clientDOS = mapper.selectList(wrapper);
        return CollUtil.isEmpty(clientDOS) ? new ArrayList<>() : convertor.toDomainObjects(clientDOS);
    }

    @Override
    public PageResponse<OAuth2Client> pageByCondition(OAuth2ClientCriteria criteria) {
        // 创建查询条件
        LambdaQueryWrapper<OAuth2ClientDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(criteria.getStatus() != null, OAuth2ClientDO::getStatus, criteria.getStatus());
        wrapper.in(criteria.getClientIds() != null, OAuth2ClientDO::getId, criteria.getClientIds());

        LocalDateTime[] createTime = criteria.getCreateTime();
        if (createTime != null) {
            if (createTime.length == 1 && createTime[0] != null) {
                wrapper.ge(OAuth2ClientDO::getCreateTime, createTime[0]);
            } else if (createTime.length > 1 && createTime[0] != null && createTime[1] != null) {
                wrapper.between(OAuth2ClientDO::getCreateTime, createTime[0], createTime[1]);
            }
        }

        wrapper.eq(!StrUtil.isEmpty(criteria.getClientCode()), OAuth2ClientDO::getClientCode, criteria.getClientCode());

        // 创建分页对象，确保使用 OAuth2ClientDO
        Page<OAuth2ClientDO> page = new Page<>(criteria.getPageIndex(), criteria.getPageSize());
        // 排序字段
        if (!StrUtil.isEmpty(criteria.getOrderBy())) {
            if (PageQuery.DESC.equals(criteria.getOrderDirection())) {
                page.addOrder(OrderItem.desc(criteria.getOrderBy()));
            } else {
                page.addOrder(OrderItem.asc(criteria.getOrderBy()));
            }
        }
        mapper.selectPage(page, wrapper);
        List<OAuth2Client> clients = convertor.toDomainObjects(page.getRecords());
        return PageResponse.of(clients, (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        OAuth2ClientDO clientDO = new OAuth2ClientDO();
        clientDO.setId(id);
        clientDO.setStatus(status);
        mapper.updateById(clientDO);
    }
}
